#include "UIMusicSelect.h"
#include "AppDelegate.h"

MusicSelectCover * MusicSelectCover::create(Size size, float borderwidth, string coverpath)
{
	auto mscv = new MusicSelectCover();
	mscv->initWithColor(Color4B::WHITE);
	mscv->size = size;
	mscv->coverpath = coverpath;
	mscv->setContentSize(size);
	mscv->coverImgArea = Rect(borderwidth + 1, borderwidth + 2, size.width - 1 - borderwidth * 2, size.height - 1 - borderwidth * 2);
	mscv->coverImg = mscv->createCoverImg();
	mscv->addChild(mscv->coverImg, 10);
	//auto cbdr = mscv->createBorder(borderwidth);
	//mscv->addChild(cbdr, 90);

	return mscv;
}

ClippingRectangleNode * MusicSelectCover::createCoverImg()
{
	auto cclp = ClippingRectangleNode::create();
	cclp->setClippingRegion(coverImgArea);

	auto clipposi = Vec2(coverImgArea.getMinX(), coverImgArea.getMinY());
	auto clipsize = Size(coverImgArea.getMaxX() - clipposi.x, coverImgArea.getMaxY() - clipposi.y);

	Sprite* cimg;
	if(!coverpath.empty()) cimg = Sprite::create(coverpath);
	else
	{
		cimg = Sprite::create();
		cimg->init();
	}
	UI::setNodeFillInArea(cimg, clipsize);
	cimg->setPosition(size.width*0.5, size.height*0.5);
	cimg->setName("coverimg");
	cclp->addChild(cimg);

	auto sl = clipsize.width / 16;
	for (int x = 0; x < 16; x++)
	{
		for (int y = 0; y < 9; y++)
		{
			auto sq = LayerColor::create(Color4B::WHITE, sl, sl);
			sq->setPosition(sl*x + clipposi.x, sl*y + clipposi.y);
			sq->runAction(
				Sequence::create(
					DelayTime::create(random<float>(0, .5f)),
					Spawn::create(
						FadeTo::create(.2f, 0),
						ScaleTo::create(.2f, 2),
						NULL
					),
					RemoveSelf::create(),
					NULL
				)
			);
			cclp->addChild(sq);
		}
	}

	startText = Label::createWithTTF("START", FONTA, 75);
	UI::setNodeAnch(startText, ANCH_BR);
	startText->setScaleX(1.25f);
	auto posy = cclp->getClippingRegion().getMaxY()*.05f;
	startText->setPosition(0, posy);
	startText->enableOutline(Color4B::BLACK, 3);
	startText->setOpacity(192);
	cclp->addChild(startText);
	startText->runAction(
		RepeatForever::create(
			Sequence::create(
				TintTo::create(.02f, pUI->themeColor3B()),
				TintTo::create(.02f, Color3B::WHITE),
				NULL
			)
		)
	);

	return cclp;
}

ClippingRectangleNode * MusicSelectCover::createBorder(float borderwidth)
{
	float width1 = borderwidth / 2;
	float width2 = borderwidth;

	auto borderclip = ClippingRectangleNode::create();
	borderclip->setClippingRegion(Rect(0, 0, size.width + 1, size.height + 1));

	float delay = .5f;

	auto linetop = LayerGradient::create(pUI->themeColorB(0), pUI->themeColorB(255), Vec2(1, 0));
	linetop->changeWidthAndHeight(size.width, width1);
	linetop->runAction(
		RepeatForever::create(
			Sequence::create(
				MoveTo::create(0, Vec2(-size.width, size.height - width1)),
				MoveTo::create(1, Vec2(size.width, size.height - width1)),
				DelayTime::create(delay),
				NULL
			)
		)
	);

	auto linebottom = LayerGradient::create(pUI->themeColorB(0), pUI->themeColorB(255), Vec2(-1, 0));
	linebottom->changeWidthAndHeight(size.width, width1);
	linebottom->runAction(
		RepeatForever::create(
			Sequence::create(
				MoveTo::create(0, Vec2(size.width, 0)),
				MoveTo::create(1, Vec2(-size.width, 0)),
				DelayTime::create(delay),
				NULL
			)
		)
	);

	auto lineleft = LayerGradient::create(pUI->themeColorB(0), pUI->themeColorB(255), Vec2(0, 1));
	lineleft->changeWidthAndHeight(width1, size.height);
	lineleft->runAction(
		RepeatForever::create(
			Sequence::create(
				MoveTo::create(0, Vec2(0, -size.height)),
				MoveTo::create(1, Vec2(0, size.height)),
				DelayTime::create(delay),
				NULL
			)
		)
	);

	auto lineright = LayerGradient::create(pUI->themeColorB(0), pUI->themeColorB(255), Vec2(0, -1));
	lineright->changeWidthAndHeight(width1, size.height);
	lineright->runAction(
		RepeatForever::create(
			Sequence::create(
				MoveTo::create(0, Vec2(size.width - width1, size.height)),
				MoveTo::create(1, Vec2(size.width - width1, -size.height)),
				DelayTime::create(delay),
				NULL
			)
		)
	);

	borderclip->addChild(linetop);
	borderclip->addChild(linebottom);
	borderclip->addChild(lineleft);
	borderclip->addChild(lineright);

	auto dn = DrawNode::create(width2);
	dn->drawLine(Vec2(0, 0), Vec2(0, size.width*0.1), Color4F::WHITE);
	dn->drawLine(Vec2(0, 0), Vec2(size.width*0.1, 0), Color4F::WHITE);
	dn->drawLine(Vec2(0, size.height), Vec2(size.width*0.1, size.height), Color4F::WHITE);
	dn->drawLine(Vec2(0, size.height), Vec2(0, size.height - size.width*0.1), Color4F::WHITE);
	dn->drawLine(Vec2(size.width, size.height), Vec2(size.width*0.9, size.height), Color4F::WHITE);
	dn->drawLine(Vec2(size.width, size.height), Vec2(size.width, size.height - size.width*0.1), Color4F::WHITE);
	dn->drawLine(Vec2(size.width, 0), Vec2(size.width*0.9, 0), Color4F::WHITE);
	dn->drawLine(Vec2(size.width, 0), Vec2(size.width, size.width*0.1), Color4F::WHITE);
	borderclip->addChild(dn);

	return borderclip;
}

void MusicSelectCover::changeCover(string newcoverpath)
{
	if (!newcoverpath.empty())
	{
		coverpath = newcoverpath;
		coverImg->runAction(
			Sequence::create(
				CallFunc::create(
					[&]
		{
			coverImg->getChildByName("coverimg")->runAction(FadeTo::create(.15f, 0));
		}
			),
				DelayTime::create(.15f),
			CallFunc::create(
				[&]
		{
			coverImg = createCoverImg();
			addChild(coverImg, 10);
		}
			),
			RemoveSelf::create(),
			NULL
			)
		);
	}
	else
	{
		coverImg->runAction(
			CallFunc::create(
				[&]
		{
			coverImg->getChildByName("coverimg")->runAction(FadeTo::create(.15f, 0));
		}
			)
		);
	}
}

void MusicSelectCover::onMouseMove(Event * e)
{
}

void MusicSelectCover::onMouseDown(Event * e)
{
	if (mouseStatus == MOUSEHOVER || mouseStatus == MOUSEENTER && mouseKey == MOUSELEFT && additionalEventActions.onMouseDown != nullptr)
	{
		runAdditionalEventAction(MOUSEDOWN);
	}
}




//========================================
//
//Music Select UI Title
//
//========================================
MusicSelectUITitle * MusicSelectUITitle::create()
{
	auto clip = new MusicSelectUITitle();
	auto clipsize = Size(frameSize.width, frameSize.height*0.1);
	UI::setNodeAnch(clip, ANCH_TR);
	clip->setContentSize(clipsize);
	clip->setPosition(Vec2(frameSize.width, frameSize.height + 2));
	clip->setClippingRegion(Rect(0, 1, clipsize.width, clipsize.height - 1));

	auto grad = LayerGradient::create(THEMECOLORBA(230), THEMECOLORBA(200), Vec2(-1, -1));
	UI::setNodeAnch(grad, ANCH_TR);
	grad->setPosition(clipsize);
	grad->changeWidthAndHeight(clipsize.width, clipsize.height);
	clip->addChild(grad);

	auto line = LayerGradient::create(pUI->textColorB(255), pUI->textColorB(255), Vec2(1, 0));
	line->changeWidthAndHeight(clipsize.width, clipsize.height*0.02);
	clip->addChild(line);

	auto pPSEmitter = ParticleSystemQuad::createWithTotalParticles(1000);
	auto tex = Director::getInstance()->getTextureCache()->addImage("image/square.png");
	tex->setAntiAliasTexParameters();
	pPSEmitter->setTexture(tex);
	pPSEmitter->setAnchorPoint(Point(0, 0));
	pPSEmitter->setDuration(-1);
	pPSEmitter->setEmitterMode(ParticleSystem::Mode::GRAVITY);
	pPSEmitter->setGravity(Point(0, 0));
	pPSEmitter->setPosition(Point(clipsize.width*0.625, clipsize.height + 80));
	pPSEmitter->setPosVar(Point(clipsize.width*0.625, 0));
	pPSEmitter->setLife(4);
	pPSEmitter->setLifeVar(2);
	pPSEmitter->setStartColor(pUI->textColorF(64));
	pPSEmitter->setStartColorVar(Color4F(0, 0, 0, .4f));
	pPSEmitter->setEndColor(pUI->textColorF(0));
	pPSEmitter->setEndColorVar(Color4F(0, 0, 0, .0f));
	pPSEmitter->setStartSize(50);
	pPSEmitter->setStartSizeVar(30);
	pPSEmitter->setEndSize(50);
	pPSEmitter->setEndSizeVar(30);
	pPSEmitter->setAngle(225);
	pPSEmitter->setAngleVar(15);
	pPSEmitter->setSpeed(100);
	pPSEmitter->setSpeedVar(15);
	pPSEmitter->setStartSpin(0.0);
	pPSEmitter->setStartSpinVar(30.0);
	pPSEmitter->setEndSpin(270.0);
	pPSEmitter->setEndSpinVar(180.0);
	pPSEmitter->setEmissionRate(30);
	clip->addChild(pPSEmitter);


	return clip;
}

void MusicSelectUITitle::addButton(string name, function<void()> func, EventHelper::MouseEventType eventType)
{
	auto topbtn = UICButton::create(Size(190, 50), name, THEMECOLORBA(0), TEXTCOLORB);
	topbtn->setPosition(frameSize.width - (topbtns.size() + 1) * 200, 2);
	topbtns.push_back(topbtn);
	addChild(topbtn);

	if (func != nullptr)
	{
		topbtn->setAdditionalEventAction(eventType, func);
	}
}

void MusicSelectUITitle::setActiveBtn(int index)
{
	for (auto btn : topbtns)
	{
		btn->setActiveStat(false);
	}
	topbtns[index]->setActiveStat(true);
}

MusicSelectInfo::MusicSelectInfo()
{
	nameStyle = TTFConfig(FONTA, 24);
	valueStyle = TTFConfig(FONTA, 32);
}

MusicSelectInfo * MusicSelectInfo::create(Size disparea)
{
	auto minf = new MusicSelectInfo();
	minf->setClippingRegion(Rect(Vec2::ZERO, disparea));
	minf->disparea = disparea;
	minf->cellheight = disparea.height / 5;

	//auto bg = LayerGradient::create(pUI->themeColorB(96), pUI->themeColorB(32), Vec2(-1, 1));
	//bg->changeWidthAndHeight(disparea.width, disparea.height);
	//minf->addChild(bg);

	minf->addInfoItem("BPM");
	minf->addInfoItem("NOTER");
	minf->addInfoItem("TOTAL NOTES (SINGLE+LONG)");
	minf->addInfoItem("LAST PLAYED");
	minf->addInfoItem("STATUS");

	//auto border = DrawNode::create(5);
	//border->drawRect(Vec2::ZERO, Vec2(disparea.width - 1, disparea.height), pUI->themeColorF(255));
	//minf->addChild(border);

	return minf;
}

void MusicSelectInfo::addInfoItem(string name)
{
	auto namelabel = Label::createWithTTF(nameStyle, name);
	UI::setNodeAnch(namelabel, ANCH_BL);
	namelabel->setTextColor(TEXTCOLORB);
	namelabel->setPosition(disparea.width*0.05f, disparea.height - cellheight*(0.4f + infoCount));
	addChild(namelabel);
	auto valuelabel = Label::createWithTTF(valueStyle, "");
	UI::setNodeAnch(valuelabel, ANCH_TR);
	valuelabel->setTextColor(TEXTCOLORB);
	valuelabel->setPosition(disparea.width*0.95f, disparea.height - cellheight*(0.35f + infoCount));
	valuelabel->setName(name);
	addChild(valuelabel);
	auto line = LayerColor::create(TEXTCOLORB, disparea.width*0.9f, 2);
	line->setPosition(Vec2(disparea.width*0.05f, disparea.height - cellheight*(0.4f + infoCount)));
	addChild(line);
	infoCount++;
}

void MusicSelectInfo::setInfoValue(MusicLevelListManager* mllst, int listindex, NoteManager* notemgr)
{
	auto act1 = Spawn::create(FadeTo::create(0, 0), SkewTo::create(0, 90, 0), NULL);
	auto act2 = EaseSineOut::create(
		Spawn::create(
			FadeTo::create(.2f, 255),
			SkewTo::create(.2f, 0, 0),
			NULL
		)
	);
	auto delay = 0.0f;
	auto delaystep = .07f;

	Label* lb = (Label*)getChildByName("BPM");
	string bpmvaluestr;
	if (mllst->listdata[listindex].bpmmax.compare(mllst->listdata[listindex].bpmmax) == 0) bpmvaluestr = mllst->listdata[listindex].bpmmax;
	else bpmvaluestr = mllst->listdata[listindex].bpmmax + "~" + mllst->listdata[listindex].bpmmax;
	lb->setString(bpmvaluestr);
	lb->stopAllActions();
	lb->runAction(Sequence::create(act1->clone(), DelayTime::create(delay += delaystep), act2->clone(), NULL));

	lb = (Label*)getChildByName("NOTER");
	lb->setString(mllst->listdata[listindex].noter);
	lb->stopAllActions();
	lb->runAction(Sequence::create(act1->clone(), DelayTime::create(delay += delaystep), act2->clone(), NULL));

	lb = (Label*)getChildByName("TOTAL NOTES (SINGLE+LONG)");
	char notes[32];
	int singlenotes, longnotes;
	int totalnotes = notemgr->getTotalNotes(singlenotes, longnotes);
	sprintf(notes, "%d ( %d + %d )", totalnotes, singlenotes, longnotes);
	lb->setString(notes);
	lb->stopAllActions();
	lb->runAction(Sequence::create(act1->clone(), DelayTime::create(delay += delaystep), act2->clone(), NULL));

	lb = (Label*)getChildByName("LAST PLAYED");
	string lastplayed = mllst->listdata[listindex].lastplayed;
	if (lastplayed == "") lastplayed = "NOT YET";
	else lastplayed = lastplayed.substr(0, 4) + "-" + lastplayed.substr(4, 2) + "-" + lastplayed.substr(6, 2);
	lb->setString(lastplayed);
	lb->stopAllActions();
	lb->runAction(Sequence::create(act1->clone(), DelayTime::create(delay += delaystep), act2->clone(), NULL));

	lb = (Label*)getChildByName("STATUS");
	string status;
	if (mllst->listdata[listindex].isfullcombo == "1") status = "FULL COMBO";
	else if (mllst->listdata[listindex].iscleared == "1") status = "CLEARED";
	else status = "NONE";
	lb->setString(status);
	lb->stopAllActions();
	lb->runAction(Sequence::create(act1->clone(), DelayTime::create(delay += delaystep), act2->clone(), NULL));
}

MusicSelectGotoPlayScene * MusicSelectGotoPlayScene::create(Size size)
{
	auto msgps = new MusicSelectGotoPlayScene();
	msgps->initWithColor(Color4B(0, 0, 0, 0));
	msgps->changeWidthAndHeight(size.width, size.height);
	//UI::setNodeAnch(msgps, ANCH_M);

	auto ptrsize = Size(frameSize.width*.05f, frameSize.width*.05f);
	auto ptr = LayerColor::create(Color4B(0, 0, 0, 0), ptrsize.width, ptrsize.width);
	auto bg1 = LayerColor::create(TEXTCOLORBA(128), ptrsize.width, ptrsize.height);
	UI::setNodeAnch(bg1, ANCH_M);
	bg1->setPosition(msgps->getAnchorPointInPoints());
	bg1->runAction(RepeatForever::create(RotateBy::create(.2f, 45)));
	ptr->addChild(bg1);

	auto bg2 = LayerColor::create(TEXTCOLORBA(64), ptrsize.width*.8f, ptrsize.height*.8f);
	UI::setNodeAnch(bg2, ANCH_M);
	bg2->setPosition(msgps->getAnchorPointInPoints());
	bg2->runAction(RepeatForever::create(RotateBy::create(.2f, 60)));
	ptr->addChild(bg2);

	auto l = Label::createWithTTF("START", FONTA, ptrsize.height*.33f);
	UI::setNodeAnch(l, ANCH_M);
	l->setPosition(msgps->getAnchorPointInPoints());
	l->runAction(RepeatForever::create(
		Sequence::create(
			FadeTo::create(.1f, 128),
			FadeTo::create(.1f, 255),
			NULL
		)
	));
	ptr->addChild(l);
	for (auto ptrchl : ptr->getChildren()) { ptrchl->setScale(0); }
	msgps->addChild(ptr);
	msgps->pointer = ptr;
	return msgps;
}

void MusicSelectGotoPlayScene::onMouseMove(Event* e)
{
	if (mouseStatus == MOUSEENTER || mouseStatus == MOUSEHOVER)
	{
		auto pos = getMouseLocInNode(this, e);
		auto anchpos = getAnchorPointInPoints();
		pos.x -= anchpos.x;
		pos.y -= anchpos.y;
		pointer->setPosition(pos);
		if (mouseStatus == MOUSEENTER || pointer->getScale() == 0)
		{
			//pointer->runAction(EaseBackOut::create(ScaleTo::create(.2f, 1)));
			for (auto node : pointer->getChildren())
			{
				node->runAction(EaseBackOut::create(ScaleTo::create(.2f, 1)));
			}
		}
	}
	else if (mouseStatus == MOUSELEAVE)
	{
		//pointer->runAction(EaseBackOut::create(ScaleTo::create(.2f, 1)));
		for (auto node : pointer->getChildren())
		{
			node->runAction(ScaleTo::create(.2f, 0));
		}
	}
}

void MusicSelectGotoPlayScene::onMouseDown(Event * e)
{
	if (mouseStatus == MOUSEENTER || mouseStatus == MOUSEHOVER)
		runAdditionalEventAction(MOUSEDOWN);
}
